/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "MusicChangerSamsung.h"
#include "Manager.h"
#include <logs/Log.h>
#include <math/utl.h>

#include <FMedia.h>

using namespace Osp::Media;

namespace liba
{
namespace noise
{

class PlayerEventListener
	: public Osp::Media::IPlayerEventListener
{
public:
	virtual void OnPlayerOpened( result r )
	{
		AppLog("Player opened r = %d", r);
	}

	virtual void OnPlayerEndOfClip(void)
	{
		AppLog("Player end of clip");
	}

	virtual void OnPlayerSeekCompleted( result r )
	{
		AppLog("Player seek completed r = %d", r);
	}

	virtual void OnPlayerBuffering(int percent)
	{
		AppLog("Player buffering (%d percent)", percent);
	}

	virtual void OnPlayerErrorOccurred( PlayerErrorReason r )
	{
		switch (r)
		{
		case PLAYER_ERROR_NONE:
			AppLog("Player error (Not defined)");
			break;
		case PLAYER_ERROR_INVALID_DATA:
			AppLog("Player error (The data is invalid)");
			break;
		case PLAYER_ERROR_CONNECTION_LOST:
			AppLog("Player error (The connection lost)");
			break;
		case PLAYER_ERROR_STREAMING_TIMEOUT:
			AppLog("Player error (The streaming timeout)");
			break;
		case PLAYER_ERROR_TRANSPORT:
			AppLog("Player error (The transport failed)");
			break;
		case PLAYER_ERROR_SERVER:
			AppLog("Player error (The server failed)");
			break;
		case PLAYER_ERROR_OUT_OF_MEOMORY:
			AppLog("Player error (Insufficient memory)");
			break;
		case PLAYER_ERROR_DEVICE_FAILED:
			AppLog("Player error (The player device failed)");
			break;
		}
	}

	virtual void OnPlayerInterrupted(void)
	{
		AppLog("Player interrupted by higher-priority task");
	}

	virtual void OnPlayerReleased(void)
	{
		AppLog("Player released by higher-priority task");
	}
};

MusicChanger::MusicChanger(double fadeout_time)
	: global_volume( 1 )
	, current_volume( 1 )
	, fadeout_speed( 1.0 / fadeout_time )
	, player(new Player())
	, eventListener(new PlayerEventListener())
{
	player->Construct(*eventListener);
	player->SetLooping(true);
}

MusicChanger::~MusicChanger()
{
	if (player)
	{
		player->Stop();
		player->Close();
	}
}

void MusicChanger::change_music(const filesystem::String & next_music)
{
	next_music_name = next_music;
}

inline int convertVolume(double volume)
{
	return static_cast<int>(99.0 * volume);
}

void MusicChanger::life_cycle(double delta_time)
{
	if( next_music_name == music_name )
	{
		current_volume += delta_time * fadeout_speed;
		current_volume = math::clamp( current_volume, 0.0, 1.0 );
		//		channel->change_attribute( noise::hard::Channel::volume_name, current_volume * global_volume );
		player->SetVolume(convertVolume(current_volume * global_volume));
	}
	else
	{
		current_volume -= delta_time * fadeout_speed;
//		channel->change_attribute( noise::hard::Channel::volume_name, current_volume * global_volume );
		player->SetVolume(convertVolume(current_volume * global_volume));

		if( current_volume < 0 || player->GetState() != PLAYER_STATE_PLAYING)
		{
//			channel->stop();
			player->Stop();
			player->Close();
			music_name = next_music_name;
			if( !music_name.empty() )
			{
				current_volume = 1;
//				channel->change_attribute( noise::hard::Channel::volume_name, current_volume * global_volume );
				player->SetVolume(convertVolume(current_volume * global_volume));
	//			channel->play( noise::Manager::create_datasource( music_name ) );
				Osp::Base::String filename = Osp::Base::String((filesystem::String("%app_path%") + "/" + music_name).c_str()) + L".m4a";
				AppLog("Player is about to open file: %S", filename.GetPointer());
				player->OpenFile(filename);
				player->Play();
			}
		}
	}
}

void MusicChanger::change_volume(double volume)
{
	global_volume = volume;
}

} // namespace noise
} // namesapce liba

